﻿
Imports osi.fs.property
Imports lock_t = lockWrapper(Of locks.eventCombLock)

Partial Public NotInheritable Class cached_property_wrapper(Of T)
    Inherits property_wrapper(Of T)
    Implements iproperty(Of T)

    Private ReadOnly l As lock_t = Nothing

    Public Sub New(ByVal p As iproperty(Of T))
        MyBase.New(p)
        l = New lock_t()
        start()
    End Sub

    Private Function locked(ByVal d As _do(Of eventComb)) As eventComb
        assert(Not d Is Nothing)
        Dim ec As eventComb = Nothing
        Return New eventComb(Function() As Boolean
                                 Return waitfor(l) AndAlso
                                        goto_next()
                             End Function,
                             Function() As Boolean
                                 ec = d()
                                 assert(Not ec Is Nothing)
                                 Return waitfor(ec) AndAlso
                                        goto_next()
                             End Function,
                             Function() As Boolean
                                 l.release()
                                 assert(ec.end_result())
                                 Return goto_end()
                             End Function)
    End Function

    Private Function unlock_waitfor_initialized(ByVal v As _do(Of Boolean)) As eventComb
        assert(Not v Is Nothing)
        Return unlock_waitfor_initialized(Function() As eventComb
                                              Return New eventComb(Function() As Boolean
                                                                       Return v() AndAlso
                                                                              goto_end()
                                                                   End Function)
                                          End Function)
    End Function

    Private Function unlock_waitfor_initialized(ByVal v As _do(Of eventComb)) As eventComb
        assert(Not v Is Nothing)
        Dim ec As eventComb = Nothing
        Return New eventComb(Function() As Boolean
                                 Return waitfor(Function() initialized) AndAlso
                                        goto_next()
                             End Function,
                     Function() As Boolean
                         ec = v()
                         Return waitfor(ec) AndAlso
                                goto_next()
                     End Function,
                     Function() As Boolean
                         Return ec.end_result() AndAlso
                                goto_end()
                     End Function)
    End Function

    Private Function unlock_get_data(ByVal p As pointer(Of T)) As eventComb
        Return unlock_waitfor_initialized(Function() eva(p, d))
    End Function

    Public Function get_data(ByVal p As pointer(Of T)) As eventComb _
                            Implements iproperty(Of T).get_data
        Return locked(Function() unlock_get_data(p))
    End Function

    Private Function unlock_set_data(ByVal value As T) As eventComb
        Return unlock_waitfor_initialized(Function() As Boolean
                                              Return eva(d, value) AndAlso update_last_update_ticks()
                                          End Function)
    End Function

    Public Function set_data(ByVal value As T) As eventComb _
                            Implements iproperty(Of T).set_data
        Return locked(Function() unlock_set_data(value))
    End Function

    Private Function unlock_get_set_data(ByVal v As _do(Of T, Boolean)) As eventComb
        assert(Not v Is Nothing)
        Return unlock_waitfor_initialized(Function() As Boolean
                                              Return v(d) AndAlso
                                                     update_last_update_ticks()
                                          End Function)
    End Function

    Public Function get_set_data(ByVal d As _do(Of T, Boolean)) As eventComb _
                                Implements iproperty(Of T).get_set_data
        Return get_set_data(get_set_data_proxy(d))
    End Function

    Private Function unlock_get_set_data(ByVal v As get_set_data_d(Of T)) As eventComb
        assert(Not v Is Nothing)
        Return unlock_waitfor_initialized(Function() As eventComb
                                              Dim p As pointer(Of T) = Nothing
                                              Dim ec As eventComb = Nothing
                                              Return New eventComb(Function() As Boolean
                                                                       p = New pointer(Of T)(d)
                                                                       ec = v(p)
                                                                       assert(Not ec Is Nothing)
                                                                       Return waitfor(ec) AndAlso
                                                                              goto_next()
                                                                   End Function,
                                                                   Function() As Boolean
                                                                       Return ec.end_result() AndAlso
                                                                              eva(d, +p) AndAlso
                                                                              update_last_update_ticks() AndAlso
                                                                              goto_end()
                                                                   End Function)
                                          End Function)
    End Function

    Public Function get_set_data(ByVal d As get_set_data_d(Of T)) As eventComb _
                                Implements iproperty(Of T).get_set_data
        Return locked(Function() unlock_get_set_data(d))
    End Function
End Class
